//
// Created by 32827 on 2024/6/24.
//
#include "yzf_tim.h"

YZF_RESULT yzf_tim_open_clock(YZF_TIM_POINTER p_tim){
    switch ((uint32_t)p_tim) {
        case (uint32_t)TIM1:
            RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;
            break;
        case (uint32_t)TIM2:
            RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
            break;
        case (uint32_t)TIM3:
            RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
            break;
        case (uint32_t)TIM5:
            RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;
            break;
        case (uint32_t)TIM6:
            RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;
        default:
            return YZF_NOT_FOUND;
    }
    return YZF_OK;
}

YZF_RESULT yzf_tim_enable(YZF_TIM_POINTER p_tim){
    p_tim->CR1 |= TIM_CR1_CEN;
    return YZF_OK;
}
YZF_RESULT yzf_tim_disable(YZF_TIM_POINTER p_tim){
    p_tim->CR1 &= ~TIM_CR1_CEN;
    return YZF_OK;
}

YZF_RESULT yzf_tim_update_event_disable(YZF_TIM_POINTER p_tim){
    p_tim->CR1 |= TIM_CR1_UDIS;
    return  YZF_OK;
}
YZF_RESULT yzf_tim_update_event_enable(YZF_TIM_POINTER p_tim){
    p_tim->CR1 &= ~TIM_CR1_UDIS;
    return  YZF_OK;
}
YZF_RESULT yzf_tim_update_source(YZF_TIM_POINTER p_tim, uint8_t source){
    p_tim->CR1 &= ~TIM_CR1_URS;
    p_tim->CR1 |= source<<TIM_CR1_URS_Pos;
    return  YZF_OK;
}
YZF_RESULT yzf_tim_set_dir(YZF_TIM_POINTER p_tim, YZF_BOOL isSub){
    p_tim->CR1 &= ~TIM_CR1_DIR;
    p_tim->CR1 |= isSub<<TIM_CR1_DIR_Pos;
    return  YZF_OK;
}
YZF_RESULT yzf_tim_set_one_pulse_mode(YZF_TIM_POINTER p_tim,YZF_BOOL isOne){
    p_tim->CR1 &= ~TIM_CR1_OPM;
    p_tim->CR1 |= isOne<<TIM_CR1_OPM_Pos;
    return  YZF_OK;
}
YZF_RESULT yzf_tim_set_clock_division(YZF_TIM_POINTER p_tim, uint8_t division){
    p_tim->CR1 &= ~TIM_CR1_CKD;
    p_tim->CR1 |= division<<TIM_CR1_CKD_Pos;
    return  YZF_OK;
}
YZF_RESULT yzf_tim_auto_reload_enable(YZF_TIM_POINTER p_tim){
    p_tim->CR1 |= TIM_CR1_ARPE;
    return  YZF_OK;
}
YZF_RESULT yzf_tim_auto_reload_disable(YZF_TIM_POINTER p_tim){
    p_tim->CR1 &= ~TIM_CR1_ARPE;
    return  YZF_OK;
}
YZF_BOOL yzf_tim_get_update_interrupt_flag(YZF_TIM_POINTER p_tim,YZF_BOOL isClear){
    YZF_BOOL flag=(p_tim->SR & TIM_SR_UIF)==TIM_SR_UIF;
    if(isClear){
        p_tim->SR &= ~TIM_SR_UIF;
    }
    return flag;
}
YZF_RESULT yzf_tim_create_update_event(YZF_TIM_POINTER p_tim){
    p_tim->EGR |= TIM_EGR_UG;
    return  YZF_OK;
}

YZF_RESULT yzf_tim_set_cnt(YZF_TIM_POINTER p_tim, uint32_t cnt){
    p_tim->CNT = cnt;
    return  YZF_OK;
}
YZF_RESULT yzf_tim_get_cnt(YZF_TIM_POINTER p_tim, uint32_t *cnt){
    *cnt = p_tim->CNT;
    return YZF_OK;
}
YZF_RESULT yzf_tim_set_prescaler(YZF_TIM_POINTER p_tim, uint16_t prescaler){
    p_tim->PSC=prescaler;
    return YZF_OK;
}
YZF_RESULT yzf_tim_get_prescaler(YZF_TIM_POINTER p_tim, uint16_t *prescaler){
    *prescaler=p_tim->PSC;
    return YZF_OK;
}
YZF_RESULT yzf_tim_set_auto_reload_number(YZF_TIM_POINTER p_tim,uint16_t arr){
    p_tim->ARR=arr;
    return YZF_OK;
}
YZF_RESULT yzf_tim_get_auto_reload_number(YZF_TIM_POINTER p_tim,uint16_t *arr){
    *arr=p_tim->ARR;
    return YZF_OK;
}

YZF_RESULT yzf_tim_select_mms(YZF_TIM_POINTER p_tim,uint16_t mms){
    YZF_MODIFY_REG(p_tim->CR2,TIM_CR2_MMS,mms,TIM_CR2_MMS_Pos);
    return  YZF_OK;
}
YZF_RESULT yzf_tim_out_compare_mode_set(YZF_TIM_POINTER p,uint16_t ch_id,uint16_t mode){
    switch (ch_id) {
        case 1:
            YZF_MODIFY_REG(p->CCMR1,TIM_CCMR1_OC1M,mode,TIM_CCMR1_OC1M_Pos);
            return YZF_OK;
        case 2:
            YZF_MODIFY_REG(p->CCMR1,TIM_CCMR1_OC2M,mode,TIM_CCMR1_OC2M_Pos);
            return YZF_OK;
        case 3:
            YZF_MODIFY_REG(p->CCMR2,TIM_CCMR2_OC3M,mode,TIM_CCMR2_OC3M_Pos);
            return YZF_OK;
        case 4:
            YZF_MODIFY_REG(p->CCMR2,TIM_CCMR2_OC4M,mode,TIM_CCMR2_OC4M_Pos);
            return YZF_OK;
        default:
            return YZF_NOT_FOUND;
    }
}
YZF_RESULT yzf_tim_capture_compare_enable(YZF_TIM_POINTER p_tim,uint16_t ch_id,YZF_BOOL isEnable){
    YZF_MODIFY_REG(p_tim->CCER,(0x1UL<<(4*(ch_id-1))),isEnable,(4*(ch_id-1)));
    return YZF_OK;
}
YZF_RESULT yzf_tim_capture_compare_data_set(YZF_TIM_POINTER p_tim,uint16_t ch_id,uint32_t data){
    YZF_MODIFY_REG(*(((uint32_t *)&p_tim->CCR1)+(ch_id-1)),TIM_CCR1_CCR1,data,TIM_CCR1_CCR1_Pos);
    return YZF_OK;
}